/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.toolkit.shape.annotation.impl;

import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

import who.tmap.bo.cd.CDProportionalSymbols;
import who.tmap.toolkit.cdr.impl.CDRPSHelper;
import who.tmap.toolkit.shape.annotation.LegendShape;

public class ProportionalSymbolsLegendShapeHelper  {

	// # Sample size in the proportional symbols legend
	private static double[] PS_SAMPLES =new double[] { 10, 50, 100 };
	// distance between ps sample and ps text
	private static final double PS_TEXT_LEGEND_FACTOR_X =1.2d;
	// distance between ps line and ps text
	private static final double PS_TEXT_LINE_GAP_FACTOR =0.2d;		
	
	private LegendShape legendShape;
	
	public ProportionalSymbolsLegendShapeHelper( LegendShape legendShape ) {
		this.legendShape =legendShape;
	}
	
	public LegendShape getLegendShape() {
		return legendShape;
	}

	public void setLegendShape(LegendShape legendShape) {
		this.legendShape = legendShape;
	}

	protected TextRenderingHelper prepareLegend( Graphics2D g, Point2D legendTextPt, double screenToMapFactor ) {
		CDProportionalSymbols cdps =(CDProportionalSymbols)legendShape.getCartographicDisplay();
		TextRenderingHelper trh =new TextRenderingHelper( screenToMapFactor, legendShape.getZoomFactor() );
		
		CDRPSHelper psHelper =new CDRPSHelper();
		psHelper.setMinVal( cdps.getMinVal() );
		psHelper.setMaxVal( cdps.getMaxVal() );
		psHelper.setMapFactor( legendShape.getMapFactor() );
		
		NumberFormat formatter =NumberFormat.getNumberInstance();
		
		trh.init( g, legendShape.getFontName(), legendShape.getFontStyle(), legendShape.getFontSize() );
		
		List<String> lines =new ArrayList<String>();
		
		if ( cdps.getMinVal() != cdps.getMaxVal() ) {
			double prevSize =0, prevY =0, prevX =0;
			
			double diff =cdps.getMaxVal() - cdps.getMinVal();

			for( int ct =PS_SAMPLES.length-1; ct >= 0 ; ct-- ) {
				double val =cdps.getMinVal() + ( diff * ( PS_SAMPLES[ ct ]/100d ) );
				double symbolSize =psHelper.computeSymbolSize( val, cdps.getScalingFactor() );
				
				lines.add( formatter.format( legendShape.isProportionalSymbolsRoundValues() 
															? Double.valueOf( val ).longValue() 
															: val ) );
			
				double x =0;
				double y =0;
				if ( prevY == 0 ) {
					y =legendTextPt.getY() - (symbolSize/2d) + trh.getLineHeight();
					x =legendShape.getPt().getX();
				} else {
					y =prevY + prevSize - symbolSize;
					x =prevX + (prevSize/2d) - (symbolSize/2d);
				}
				
				legendShape.getLegendSamples().add( new LegendSample( new Point2D.Double( x, y ), symbolSize ) );	
				
				prevSize =symbolSize;
				prevX =x;
				prevY =y;
			}		
		}
		
		// Not the best way to do it
		double maxSize =psHelper.computeSymbolSize( cdps.getMaxVal(), cdps.getScalingFactor() );
		Point2D pt =new Point2D.Double( legendTextPt.getX() + maxSize
									  , legendTextPt.getY() );
		
		trh.prepareTextForRendering( g, lines, pt
									  , TextRenderingHelper.NO_MARGINS );
		
		return trh;
	}
	
	public void renderProportionalSymbols( Graphics2D g, TextRenderingHelper trhLegend ) {

		List<TextRenderingTextLine> lines =trhLegend.getTextLines();
		
		double lineX =0;
		double sampleCenterX =0;
		
		for( int ct =0; ct < legendShape.getLegendSamples().size(); ct++ ) {
			LegendSample ls =legendShape.getLegendSamples().get(ct);
			ls.draw( g );

			// Process x for text legend
			if ( ct == 0 ) {
				lineX =ls.getPt().getX() + ( ls.getPsSize() * PS_TEXT_LEGEND_FACTOR_X );
				sampleCenterX =ls.getPt().getX() + ( ls.getPsSize() / 2d );
			}
			
			TextRenderingTextLine line =lines.get( ct );
			line.setX( lineX );
			line.setY( ls.getPt().getY() );
			
		}
		
		Rectangle2D rect =trhLegend.getBounds();
		//rect.setRect( lineX, rect.getMinY(), rect.getMaxX()-lineX, rect.getHeight() );
		rect.setRect( lineX, rect.getMinY(), rect.getWidth(), rect.getHeight() );
		trhLegend.renderText( g, legendShape.isBackgroundTransparent(), legendShape.getBackgroundColor() ); 
		
		for( LegendSample ls : legendShape.getLegendSamples() ) {
			Line2D line2D =new Line2D.Double( sampleCenterX, ls.getPt().getY()
											, lineX - ( ( lineX - sampleCenterX ) * PS_TEXT_LINE_GAP_FACTOR )
											, ls.getPt().getY() );
			g.draw( line2D );
		}
	}

}
